//
//  CPJRefreshControl.swift
//  Sina
//
//  Created by YYY on 2017/8/21.
//  Copyright © 2017年 成品家（北京）网路科技有限公司. All rights reserved.
//


import UIKit

//定义刷新状态切换的临界点
private let CPJRefreshOffset: CGFloat = 123


/// 刷新状态
///
/// - Normal: 普通状态
/// - Pulling: 超过临界点，如果放手，开始刷新
/// - WillRefresh: 用户超过临界点，并且放手
enum CPJRefreshState
{
    case Normal
    case Pulling
    case WillRefresh
}

class CPJRefreshControl: UIControl {

    //所有刷新控件的父视图
    private weak var scrollView: UIScrollView?
    
    //刷新控件的懒加载
    fileprivate lazy var refreshView: CPJRefreshControlView = CPJRefreshControlView.refreshView()
    //构造函数(纯代码)
    init()
    {
        super.init(frame: CGRect())
        setupUI()
    }
    //xib画的
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
        //setupUI()
    }
    
    func beginRefreshing()
    {
        //开始刷新
        guard let sv = scrollView else
        {
            return
        }
        if refreshView.refreshState == .WillRefresh
        {
            return
        }
        refreshView.refreshState = .WillRefresh
        
        var inset = sv.contentInset
        
        inset.top += CPJRefreshOffset
        sv.contentInset = inset
        
        refreshView.parentHeight = CPJRefreshOffset
    }
    
    func endRefreshing()
    {
        //结束刷新
        print("结束刷新")
        guard let sv = scrollView else
        {
            return
        }
        if refreshView.refreshState != .WillRefresh
        {
            return
        }
        refreshView.refreshState = .Normal
        var inset = sv.contentInset
        
        inset.top -= CPJRefreshOffset
        sv.contentInset = inset
    }

    //willMove中添加监听者
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        //父视图
        guard let tempScrollView = newSuperview as? UIScrollView  else
        {
            return
        }
        scrollView = tempScrollView
    
        //添加监听者
        scrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
       
    }
    
    // KVO方法
    /*
     1:所有的KVO会统一调用此方法
     2:在程序中，通常只监听某一个对象的多个属性，如果属性太多，方法会很乱。
     3:观察者模式，在不需要的时候，都需要释放。
     4:通知中心：如果不释放，什么也不发生，但是会有内存泄露，会有多次注册的可能。
     5:KVO如果不释放，会崩溃。
     */
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
    {
        guard let sv = scrollView else
        {
            return
        }
        let height = -(sv.contentOffset.y + sv.contentInset.top)
        
        if height < 0
        {
            return
        }
        self.frame = CGRect(x: 0, y: -height, width: sv.frame.size.width, height: height)
        //父视图高度
        refreshView.parentHeight = height
        
        //判断临界点
        if sv.isDragging
        {
            //拖拽中
            if height > CPJRefreshOffset && (refreshView.refreshState == .Normal)
            {
                refreshView.refreshState = .Pulling
                print("放手刷新")
            }
        
            else if height <= CPJRefreshOffset && (refreshView.refreshState == .Pulling)
            {
                refreshView.refreshState = .Normal
                print("继续用力..")
            }
            
        }
        else
        {
            if refreshView.refreshState == .Pulling
            {
                beginRefreshing()
                
                sendActions(for: .valueChanged)
                print("准备开始刷新")
            }
          
            //放手
        }
    }
    
    
    //removeFromSuperview移除监听者
    //本视图从父视图上移除
    //所有的下拉刷新框架都是监听父视图的contentOffset
    override func removeFromSuperview()
    {
        //父视图存在
        //移除监听者
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
        //父视图不存在
    }
}


extension CPJRefreshControl
{
    fileprivate func setupUI()
    {
        //设置超出边界不显示
        //clipsToBounds = true

        addSubview(refreshView)
 
        refreshView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshView.bounds.width))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshView.bounds.height))
    }
}
